﻿Imports System.Text.RegularExpressions

Public Class frmMailTask
    Friend TaskID As Integer ' 0为 新增 
    Private SmtpSetup As Config.SmtpSetup
    Private bStatus As Boolean = False
    Private myThread As Threading.Thread
    Private dsMailList As DataSet
    Private oSmtpSender As dooll.Common.SmtpSender
    Private TotalCount, SentCount, ErrCount, WaitCount, SendInteval, CheckInteval As Integer
    Private ErrMailAddr, ErrMessage, ErrID As String

    Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnStart.Click
        If Not CheckMailContent() Then
            Return
        End If
        UpdateStatus(True)
        ServiceStart()
    End Sub

    REM 加载配置信息
    Private Sub InitAppConfigValue()
        cbCheckInteval.Text = CStr(SmtpSetup.CheckInteval)
        cbSendInteval.Text = CStr(SmtpSetup.SendInteval)
        Dim SelectedText As String = String.Empty
        cbFrom.Items.Clear()
        If SmtpSetup.Accounts Is Nothing Then
            Return
        End If
        Dim Account As Config.Account
        For i As Integer = 0 To SmtpSetup.Accounts.Count - 1

            Account = CType(SmtpSetup.Accounts(i), Config.Account)

            If Account Is Nothing Or String.IsNullOrEmpty(Account.Name) Then
                cbFrom.Items.Add(String.Concat("(Mail)", Account.Mail))
            Else
                cbFrom.Items.Add(Account.Name)
            End If
        Next

        cbFrom.SelectedIndex = cbFrom.FindStringExact(SmtpSetup.SelectedAccount)

        dlgOpenFile.Filter = "文本文件(*.txt)|*.txt|网页文件(*.html,*.html)|*.html;*.htm"
    End Sub


    Private Sub MailTask_FormClosed(ByVal sender As Object, ByVal e As System.Windows.Forms.FormClosedEventArgs) Handles Me.FormClosed
        myThread = Nothing
    End Sub

    Private Sub MailTask_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
        SmtpSetup = Config.SmtpConfig.Load(False)
        InitAppConfigValue()
    End Sub

    Private Sub Button1_Click_1(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
        If dlgOpenFile.ShowDialog() = Windows.Forms.DialogResult.OK Then
            InitFileContent()
        End If
    End Sub

    Private Sub InitFileContent()
        tbFileName.Text = dlgOpenFile.FileName
        rtbBody.Text = IO.File.ReadAllText(dlgOpenFile.FileName, System.Text.Encoding.UTF8)
    End Sub

    Private Sub cbFrom_SelectedIndexChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles cbFrom.SelectedIndexChanged
        cbCheckInteval.Text = CStr(SmtpSetup.CheckInteval)
        cbSendInteval.Text = CStr(SmtpSetup.SendInteval)
    End Sub

    Private Function CheckMailContent() As Boolean
        If String.IsNullOrEmpty(tbSubject.Text) Then
            MsgBox("未设定邮件发送的标题！！！", MsgBoxStyle.Exclamation, "警告")
            Return False
        End If
        If String.IsNullOrEmpty(rtbBody.Text) Then
            MsgBox("请选择邮件发送的内容！！！", MsgBoxStyle.Exclamation, "警告")
            Return False
        End If
        Return True
    End Function

    Private Sub ServiceStart()

        If Not myThread Is Nothing Then
            myThread = Nothing
        End If

        Dim Account As Config.Account = SmtpSetup.Accounts.Find(cbFrom.Text)
        If Not Account Is Nothing Then
            oSmtpSender = New dooll.Common.SmtpSender(Account)
        Else
            MsgBox("Config.Account类实例不存在!!")
            UpdateStatus(False)
            Return
        End If
        Account = Nothing
        Try
            Using DataBase As New Data.MsSql
                dsMailList = New DataSet
                DataBase.ExecProc("sp_GetQueueList", dsMailList, "T_EmailQueue")
            End Using

            TotalCount = dsMailList.Tables(0).DefaultView.Count
            SendInteval = CInt(cbSendInteval.Text)
            MsgBox(CInt(cbCheckInteval.Text))
            If TotalCount > 0 Then
                pbSending.Maximum = TotalCount
                WaitCount = TotalCount
                myThread = New Threading.Thread(New Threading.ParameterizedThreadStart(AddressOf SendMail))
                Dim mail As New Mail
                mail.Subject = tbSubject.Text
                mail.Content = rtbBody.Text
                myThread.Start(mail)
                mail = Nothing
            End If
        Catch ex As Exception
            MsgBox(String.Concat("启动失败,原因:", ex.Message), MsgBoxStyle.Exclamation, "警告")
        End Try

    End Sub

    Private Sub UpdateLabel()
        lblStaus.Text = String.Format("错误: {0} / 成功: {1} / 总: {2}", ErrCount, SentCount, TotalCount)
        pbSending.Value = TotalCount - WaitCount
        dgvResult.Rows.Add(String.Format("{0}|{1}|{2}", ErrID, ErrMailAddr, ErrMessage).Split(CChar("|")))
    End Sub

    Private Sub SendMail(ByVal mail As Mail)
        Dim mi As New Windows.Forms.MethodInvoker(AddressOf UpdateLabel)
        SentCount = 0
        ErrCount = 0
        Dim IsSendOK As Boolean
        For I As Integer = 0 To TotalCount - 1
            Try
                If Not bStatus Then
                    Threading.Thread.Sleep(Threading.Timeout.Infinite)
                    Return
                End If

                If String.IsNullOrEmpty(CStr(dsMailList.Tables(0).Rows(I).Item("F_Email"))) Then
                    ErrMailAddr = "---"
                    WaitCount = WaitCount - 1
                    ErrCount = ErrCount + 1
                    ErrMessage = "失败 邮件为空。"
                    Me.Invoke(mi)
                    Continue For
                End If

                ErrMailAddr = dsMailList.Tables(0).Rows(I).Item("F_Email").ToString().Trim()
                ErrID = dsMailList.Tables(0).Rows(I).Item("ID").ToString()

                If String.IsNullOrEmpty(ErrMailAddr) Then
                    WaitCount = WaitCount - 1
                    ErrCount = ErrCount + 1
                    ErrMessage = "失败 邮件为空。"
                    Me.Invoke(mi)
                    Continue For
                End If

                IsSendOK = Regex.IsMatch(ErrMailAddr, "^([a-zA-Z0-9_\-\.]+)@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.)|(([a-zA-Z0-9\-]+\.)+))([a-zA-Z]{2,4}|[0-9]{1,3})$")

                If IsSendOK Then
                    Using DataBase As New Data.MsSql
                        If oSmtpSender.send(ErrMailAddr, mail.Subject, mail.Content, Nothing, Net.Mail.MailPriority.Normal, True, System.Text.Encoding.UTF8) Then
                            WaitCount = WaitCount - 1
                            SentCount = SentCount + 1
                            IsSendOK = True
                            ErrMessage = "成功。"
                            DataBase.ExecSql(String.Concat("delete from T_EmailQueue where F_Email='", ErrMailAddr, "'"))
                        Else
                            WaitCount = WaitCount - 1
                            ErrCount = ErrCount + 1
                            IsSendOK = False
                            ErrMessage = String.Format("失败 {0}。", oSmtpSender.ErrMessage)
                            DataBase.ExecSql(String.Concat("Update T_Company_Contact set F_IsValidMail=0 where F_Email='", ErrMailAddr, "'"))
                        End If
                    End Using
                Else
                    WaitCount = WaitCount - 1
                    ErrCount = ErrCount + 1
                    ErrMessage = "邮件格式错误"
                End If

                If I Mod SendInteval = 0 Then
                    Threading.Thread.Sleep(CheckInteval * 1000)
                End If
            Catch ex As Exception
                WaitCount = WaitCount - 1
                ErrCount = ErrCount + 1
                ErrMailAddr = "---------------"
                ErrMessage = String.Format("失败 {0}", ex.Message)
                REM MsgBox(String.Format("发件邮件(SendMail)出错:{0}", ex.Message))
            Finally
                Me.Invoke(mi)
            End Try
        Next
        mi = Nothing
        bStatus = False
        Me.Invoke(New Windows.Forms.MethodInvoker(AddressOf UpdateStatus))
    End Sub

    REM 设成指定状态
    Private Sub UpdateStatus(ByVal b As Boolean)
        bStatus = b
        UpdateStatus()
    End Sub

    REM 根据状态设定按键状态
    Private Sub UpdateStatus()
        If bStatus Then
            btnStop.Enabled = True
            btnStart.Enabled = False
        Else
            btnStop.Enabled = False
            btnStart.Enabled = True
        End If
    End Sub

    Protected Overrides Sub Finalize()
        If myThread.ThreadState = Threading.ThreadState.Running Or myThread.ThreadState = Threading.ThreadState.Suspended Then
            myThread.Abort()
        End If
        myThread = Nothing
        MyBase.Finalize()
    End Sub

    Private Sub btnStop_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnStop.Click
        UpdateStatus(False)
    End Sub
End Class

Friend Class Mail
    Public Subject As String
    Public Content As String
End Class